package com.ld.hpfs.common.utils;
/*
 * 存放实体
 */
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;

public abstract class Entity implements Serializable {
    protected Integer hid;
    protected Integer companyId;
    protected Integer updateId;
    protected String updateName;
    protected String updateTime;
    
    public Integer getHid() {
        return this.hid;
    }

    public void setHid(Integer hid) {
    	this.hid = hid;
    }

    public Integer getCompanyId() {
		return companyId;
	}

	public void setCompanyId(Integer companyId) {
		this.companyId = companyId;
	}

	public Integer getUpdateId() {
		return updateId;
	}

	public void setUpdateId(Integer updateId) {
		this.updateId = updateId;
	}

	public String getUpdateName() {
		return updateName;
	}

	public void setUpdateName(String updateName) {
		this.updateName = updateName;
	}

	public String getUpdateTime() {
		return updateTime;
	}

	public void setUpdateTime(String updateTime) {
		this.updateTime = updateTime;
	}

	public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        final Entity entity = (Entity) o;

        if (hid != null ? !hid.equals(entity.hid) : entity.hid != null) return false;
        if (companyId != null ? !companyId.equals(entity.companyId) : entity.companyId != null) return false;
        if (updateId != null ? !updateId.equals(entity.updateId) : entity.updateId != null) return false;
        if (updateName != null ? !updateName.equalsIgnoreCase(entity.updateName) : entity.updateName != null) return false;
        if (updateTime != null ? !updateTime.equalsIgnoreCase(entity.updateTime) : entity.updateTime != null) return false;

        return true;
    }

    public String toString() {
        return getClass().getName() + " <hid=" + getHid() + ", companyId=" + getCompanyId() + ", updateName=" + getUpdateName() + ", updateTime=" + getUpdateTime() + ">";
    }

    /**
     * Clear the values of all the fields, set to null.
     * After clearing, the object can be reused as a new one.
     */
    public void clear() {
        try {
            Field[] fields = obtainNotFinalFields(this);
            for (Field field : fields) {
                if (!Modifier.isPublic(field.getModifiers())) {
                    field.setAccessible(true);
                }
                field.set(this, null);
            }
        } catch (Exception e) {
            log.error(e);
        }
    }

    /**
     * Copy the field values of the source entity.
     */
    public void copy(Entity source) {
        if (!getClass().isAssignableFrom(source.getClass())) {
            throw new IllegalArgumentException("The target class should be assignable from the source class.");
        }

        try {
            Field[] fields = obtainNotFinalFields(this);
            for (Field field : fields) {
                if (!Modifier.isPublic(field.getModifiers())) {
                    field.setAccessible(true);
                }
                field.set(this, field.get(source));
            }
        } catch (Exception ex) {
            log.error(this, ex);
        }
    }

    /**
     * Copy the field values of the source entity.
     */
    public void copyKeys(Entity source) {
        try {
            Field[] fields = obtainNotFinalFields(this);
            for (Field field : fields) {
                if (!Modifier.isPublic(field.getModifiers())) {
                    field.setAccessible(true);
                }
                if (field.getName().equals("hid") || field.getName().equals("companyId") || field.getName().equals("updateId") || field.getName().equals("updateName") || field.getName().equals("updateTime")) {
                    field.set(this, field.get(source));
                }
            }
        } catch (Exception ex) {
            log.error(this, ex);
        }
    }

    /**
     * Clone an entity object whose class must decleare a non-parameter constructors.
     */
    public Object clone() {
        Object clone = null;

        try {
            Constructor[] constructors = getClass().getDeclaredConstructors();
            for (Constructor constructor : constructors) {
                if (constructor.getParameterTypes().length == 0) {
                    if (!Modifier.isPublic(constructor.getModifiers())) {
                        constructor.setAccessible(true);
                    }
                    clone = constructor.newInstance();
                }
            }

            if (clone != null) {
                Field[] fields = obtainNotFinalFields(this);
                for (Field field : fields) {
                    if (!Modifier.isPublic(field.getModifiers())) {
                        field.setAccessible(true);
                    }
                    field.set(clone, field.get(this));
                }
            }
        } catch (Exception ex) {
            log.error(this, ex);
        }

        return clone;
    }

    /**
     * obtains all fields without final and static modifier.
     */
    protected static Field[] obtainNotFinalFields(Object obj) {
        List<Field> fieldList = new ArrayList<Field>();

        Class clazz = obj.getClass();
        while (clazz != null) {
            for (Field field : clazz.getDeclaredFields()) {
                if (!Modifier.isFinal(field.getModifiers()) && !Modifier.isStatic(field.getModifiers())) {
                    fieldList.add(field);
                }
            }
            clazz = clazz.getSuperclass();
        }

        return fieldList.toArray(new Field[fieldList.size()]);
    }

    private static Log log = LogFactory.getLog(Entity.class);
}